import type { ParseResult } from '../../types';

/**
 * LaTeX解析器 - 负责解析LaTeX代码为抽象语法树
 */
export class LatexParser {
  /**
   * 解析LaTeX代码
   * @param latex LaTeX代码
   * @returns 解析结果
   */
  static parse(latex: string): ParseResult {
    try {
      // 基础验证
      if (!latex || typeof latex !== 'string') {
        return {
          success: false,
          error: '空的LaTeX代码'
        };
      }

      // 简单的AST构建（这里是一个简化版本，实际项目可能需要更复杂的解析）
      const ast = this.buildBasicAST(latex);

      return {
        success: true,
        ast
      };
    } catch (error) {
      console.error('LaTeX解析错误:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : '解析失败'
      };
    }
  }

  /**
   * 构建基础AST（简化版）
   */
  private static buildBasicAST(latex: string): any {
    const ast = {
      type: 'root',
      content: latex,
      children: [] as any[]
    };

    // 识别基本结构
    this.parseExpressions(latex, ast.children);

    return ast;
  }

  /**
   * 解析表达式
   */
  private static parseExpressions(latex: string, parent: any[]): void {
    // 这里是一个简化的解析器，实际项目中应该使用更复杂的词法分析和语法分析
    // 识别一些基本的LaTeX结构
    const patterns = [
      // 识别命令
      /\\[a-zA-Z]+/g,
      // 识别数学符号
      /[+\-*/=<>≠≤≥±×÷]/g,
      // 识别下标
      /_[{]([^}]*)[}]/g,
      // 识别上标
      /[^{](\^[{]([^}]*)[}])/g,
      // 识别分数
      /\\frac[{]([^}]*)[}][{]([^}]*)[}]/g,
      // 识别平方根
      /\\sqrt(?:[{](\d+)[}])?[{]([^}]*)[}]/g,
      // 识别积分
      /\\int(?:[{]([^}]*)[}][{]([^}]*)[}])?/g,
      // 识别求和
      /\\sum(?:[{]([^}]*)[}][{]([^}]*)[}])?/g
    ];

    let lastIndex = 0;

    // 简单分词处理
    patterns.forEach(pattern => {
      let match;
      while ((match = pattern.exec(latex)) !== null) {
        if (match.index > lastIndex) {
          // 添加文本节点
          const text = latex.substring(lastIndex, match.index).trim();
          if (text) {
            parent.push({
              type: 'text',
              content: text
            });
          }
        }

        // 分析匹配的内容类型
        if (match[0].startsWith('\\frac')) {
          // 分数
          parent.push({
            type: 'frac',
            numerator: match[1],
            denominator: match[2]
          });
        } else if (match[0].startsWith('\\sqrt')) {
          // 平方根
          parent.push({
            type: 'sqrt',
            index: match[1] || '',
            content: match[2]
          });
        } else if (match[0].startsWith('\\int')) {
          // 积分
          parent.push({
            type: 'integral',
            lowerLimit: match[1] || '',
            upperLimit: match[2] || ''
          });
        } else if (match[0].startsWith('\\sum')) {
          // 求和
          parent.push({
            type: 'sum',
            lowerLimit: match[1] || '',
            upperLimit: match[2] || ''
          });
        } else if (match[0].startsWith('\\')) {
          // 命令
          parent.push({
            type: 'command',
            name: match[0].substring(1)
          });
        } else if (match[0].startsWith('_')) {
          // 下标
          parent.push({
            type: 'subscript',
            content: match[1]
          });
        } else if (match[0].includes('^')) {
          // 上标
          parent.push({
            type: 'superscript',
            content: match[2]
          });
        } else {
          // 符号
          parent.push({
            type: 'symbol',
            content: match[0]
          });
        }

        lastIndex = match.index + match[0].length;
      }
    });

    // 添加剩余文本
    if (lastIndex < latex.length) {
      const text = latex.substring(lastIndex).trim();
      if (text) {
        parent.push({
          type: 'text',
          content: text
        });
      }
    }
  }

  /**
   * 从AST生成LaTeX代码
   * @param ast 抽象语法树
   * @returns LaTeX代码
   */
  static generateLatex(ast: any): string {
    if (!ast) return '';

    switch (ast.type) {
      case 'root':
        return ast.children.map((child: any) => this.generateLatex(child)).join('');
      case 'text':
        return ast.content;
      case 'command':
        return `\\${ast.name}`;
      case 'symbol':
        return ast.content;
      case 'subscript':
        return `_{${ast.content}}`;
      case 'superscript':
        return `^{${ast.content}}`;
      case 'frac':
        return `\\frac{${ast.numerator}}{${ast.denominator}}`;
      case 'sqrt':
        if (ast.index) {
          return `\\sqrt[${ast.index}]{${ast.content}}`;
        }
        return `\\sqrt{${ast.content}}`;
      case 'integral':
        if (ast.lowerLimit && ast.upperLimit) {
          return `\\int_{${ast.lowerLimit}}^{${ast.upperLimit}}`;
        }
        return '\\int';
      case 'sum':
        if (ast.lowerLimit && ast.upperLimit) {
          return `\\sum_{${ast.lowerLimit}}^{${ast.upperLimit}}`;
        }
        return '\\sum';
      default:
        return '';
    }
  }

  /**
   * 检查LaTeX语法错误
   * @param latex LaTeX代码
   * @returns 错误信息（如果有）
   */
  static checkSyntax(latex: string): string | null {
    // 检查括号匹配
    const bracketStack: string[] = [];
    const bracketPairs: { [key: string]: string } = {
      '(': ')',
      '[': ']',
      '{': '}'
    };

    for (let i = 0; i < latex.length; i++) {
      const char = latex[i];

      // 跳过转义字符后的括号
      if (i > 0 && latex[i - 1] === '\\') continue;

      if (bracketPairs[char]) {
        bracketStack.push(char);
      } else if (Object.values(bracketPairs).includes(char)) {
        const lastBracket = bracketStack.pop();
        if (!lastBracket || bracketPairs[lastBracket] !== char) {
          return `括号不匹配: 位置 ${i + 1}`;
        }
      }
    }

    if (bracketStack.length > 0) {
      return `缺少右括号: ${bracketStack.map(b => bracketPairs[b]).join(', ')}`;
    }

    // 检查未闭合的命令
    const unclosedCommands = this.findUnclosedCommands(latex);
    if (unclosedCommands.length > 0) {
      return `可能缺少参数的命令: ${unclosedCommands.join(', ')}`;
    }

    return null;
  }

  /**
   * 查找可能缺少参数的命令
   */
  private static findUnclosedCommands(latex: string): string[] {
    const commands = latex.match(/\\[a-zA-Z]+(?![a-zA-Z]|\{)/g) || [];
    const commandsThatNeedArgs = ['frac', 'sqrt', 'sum', 'prod', 'lim'];
    
    return commands
      .map(cmd => cmd.substring(1))
      .filter(cmd => commandsThatNeedArgs.includes(cmd));
  }

  /**
   * 获取光标位置的上下文信息
   * @param latex LaTeX代码
   * @param position 光标位置
   * @returns 上下文信息
   */
  static getContextAtPosition(latex: string, position: number): any {
    const beforeCursor = latex.substring(0, position);
    const afterCursor = latex.substring(position);
    
    // 查找光标前的命令
    const commandMatch = beforeCursor.match(/\\[a-zA-Z]*$/);
    const currentCommand = commandMatch ? commandMatch[0] : '';

    return {
      currentCommand,
      beforeCursor,
      afterCursor,
      // 可以扩展更多上下文信息
    };
  }
}